home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
020a
/
dvpt20.zip
/
ULAW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-12
|
6KB
|
285 lines
/****************************************************************/
/* */
/* Digitized Voice Programmer's Toolkit */
/* ------------------------------------ */
/* */
/* Simple Mu-Law File Encoder */
/* */
/* Copyright (c) 1991, Farpoint Software */
/* */
/****************************************************************/
/* This source file is not commented, but it is relatively easy */
/* to follow. The program reads a voice data file and writes an */
/* output file which has been compressed 2:1 by encoding each */
/* sample (byte) into a nybble extracted from a lookup table. */
/* The lookup table approximates a highly quantized version of */
/* the standard Mu-Law curve widely used in telephone communi- */
/* cations. */
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <stdio.h>
#include <stddef.h>
#include <malloc.h>
/*-------------------------------------------------------------------*/
char logo[] = "Simple Mu-Law File Encoder\r\n"
"Copyright(c) 1991, Farpoint Software\r\n";
unsigned char *s_buffer;
unsigned char *d_buffer;
int s_handle,d_handle;
long histogram[256];
int ctable[256] =
{
// 33 slots
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
// 48 slots
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
// 24 slots
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
// 12 slots
3,3,3,3,3,3,3,3,3,3,3,3,
// 6 slots
4,4,4,4,4,4,
// 3 slots
5,5,5,
// 1 slots
6,
// 1 slots
7,
// 1 slots
8,
// 1 slots
9,
// 3 slots
10,10,10,
// 6 slots
11,11,11,11,11,11,
// 12 slots
12,12,12,12,12,12,12,12,12,12,12,12,
// 24 slots
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
13,13,13,13,
// 48 slots
14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
14,14,14,14,14,14,14,14,
// 33 slots
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15
};
char errmsg1[] = "File read error.";
char errmsg2[] = "File write error.";
char errmsg3[] = "Unable to allocate memory.";
/*-------------------------------------------------------------------*/
void main(argc,argv)
int argc;
char **argv;
{
long s_len;
unsigned int blocks, oddblock;
unsigned int i, j;
int adjustment;
long histmax1, histmax2;
unsigned int index1, index2;
int tempvar;
puts(logo);
for ( i = 0 ; i < 256 ; i++ )
histogram[i] = 0L;
if (argc != 3)
{
puts("\nCommand line:");
puts(" ULAW <source file> <dest file>\n");
exit(1);
}
argv++;
s_handle = open(*argv,O_BINARY|O_RDONLY);
if (s_handle == -1)
{
puts(errmsg1);
exit(1);
}
argv++;
d_handle = open(*argv,O_BINARY|O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE);
if (d_handle == -1)
{
close(s_handle);
puts(errmsg2);
exit(1);
}
s_buffer = (unsigned char *)malloc(32768U);
if (s_buffer == NULL)
{
puts(errmsg3);
close(s_handle);
close(d_handle);
exit(1);
}
d_buffer = (unsigned char *)malloc(16384U);
if (d_buffer == NULL)
{
puts(errmsg3);
free(s_buffer);
close(s_handle);
close(d_handle);
exit(1);
}
s_len = filelength(s_handle);
blocks = (unsigned int)(s_len >> 15);
oddblock = (unsigned int)(s_len & 0x7FFF);
for ( i = 0 ; i < blocks ; i++ )
{
if ( read(s_handle, s_buffer, 32768U) != 32768U )
{
close(s_handle);
close(d_handle);
free(s_buffer);
free(d_buffer);
puts(errmsg1);
exit(1);
}
for ( j = 0 ; j < 32768U ; j++ )
histogram[s_buffer[j]]++;
}
if ( oddblock )
{
if ( (unsigned int)read(s_handle, s_buffer, oddblock) != oddblock )
{
close(s_handle);
close(d_handle);
free(s_buffer);
free(d_buffer);
puts(errmsg1);
exit(1);
}
for ( j = 0 ; j < oddblock ; j++ )
histogram[s_buffer[j]]++;
}
lseek(s_handle, 0L, SEEK_SET);
histmax1 = 0L;
histmax2 = 0L;
index1 = 0;
index2 = 0;
for ( i = 0 ; i < 256 ; i++ )
{
if ( histmax1 < histogram[i] )
{
histmax1 = histogram[i];
index1 = i;
}
}
for ( i = 0 ; i < 256 ; i++ )
{
if ( i != index1 )
{
if ( histmax2 < histogram[i] )
{
histmax2 = histogram[i];
index2 = i;
}
}
}
if ( abs(index1 - index2) > 8 )
adjustment = 0;
else
adjustment = 0x7F - ((int)(index1 + index2) / 2);
for ( i = 0 ; i < blocks ; i++ )
{
if ( read(s_handle, s_buffer, 32768U) != 32768U )
{
close(s_handle);
close(d_handle);
free(s_buffer);
free(d_buffer);
puts(errmsg1);
exit(1);
}
for ( j = 0 ; j < 32768U ; j++ )
{
tempvar = s_buffer[j] + adjustment;
if ( tempvar < 0 )
tempvar = 0;
else if ( tempvar > 255 )
tempvar = 255;
s_buffer[j] = (unsigned char)tempvar;
}
for ( j = 0 ; j < 16384 ; j++ )
d_buffer[j] = (unsigned char)(ctable[s_buffer[2*j]] |
(ctable[s_buffer[2*j+1]] << 4) );
if ( write(d_handle, d_buffer, 16384U) != 16384U )
{
close(s_handle);
close(d_handle);
free(s_buffer);
free(d_buffer);
puts(errmsg2);
exit(1);
}
}
if ( oddblock )
{
if ( (unsigned int)read(s_handle, s_buffer, oddblock) != oddblock )
{
close(s_handle);
close(d_handle);
free(s_buffer);
free(d_buffer);
puts(errmsg1);
exit(1);
}
for ( j = 0 ; j < oddblock ; j++ )
{
tempvar = s_buffer[j] + adjustment;
if ( tempvar < 0 )
tempvar = 0;
else if ( tempvar > 255 )
tempvar = 255;
s_buffer[j] = (unsigned char)tempvar;
}
for ( j = 0 ; j < oddblock / 2 ; j++ )
d_buffer[j] = (unsigned char)(ctable[s_buffer[2*j]] |
(ctable[s_buffer[2*j+1]] << 4) );
if ( (unsigned int)write(d_handle, d_buffer, oddblock / 2) != oddblock / 2 )
{
close(s_handle);
close(d_handle);
free(s_buffer);
free(d_buffer);
puts(errmsg2);
exit(1);
}
}
puts("File compression complete.");
close(s_handle);
close(d_handle);
free(s_buffer);
free(d_buffer);
exit(0);
}